package com.xxx.controller;

import java.io.OutputStream;
import java.text.MessageFormat;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import com.xxx.constant.RedisConstants;
import com.xxx.qrcode.QRCodeUtil;
import com.xxx.util.IpUtil;
import com.xxx.util.JedisUtil;
import com.xxx.util.ShortUrlUtil;

/**
 * 二维码生成与解析、以及短链接生成和解析相关Controller
 */
@Controller
public class QrCodeController extends BaseController {
	
	private static final Logger logger = LoggerFactory.getLogger(QrCodeController.class);
	
	 /**
     * 生成PDF文件，并下载到本地
     */
    @RequestMapping("/qrCode")
    public void qrCode(HttpServletRequest request, HttpServletResponse response){
    	logger.info("enter method qrCode().");
    	
    	try {
    		// 二维码里的内容
    		String content = request.getParameter("content");
    		System.out.println("content:"+content);
    		if(StringUtils.isEmpty(content)) {
    			return;
    		}
    		
    		// 嵌入二维码的LOGO图片
    		String logoPath = "d:/qrCode/logo.jpg";
    		
    		OutputStream os = response.getOutputStream();
    		
    		if(StringUtils.isEmpty(logoPath)) {
    			QRCodeUtil.encode(content, os);
    		} else {
    			QRCodeUtil.encode(content, logoPath, os);
    		}
    		
            os.flush();
            os.close();
    		
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    }
    
    /**
     * 将长链接转换成短链接，并生成二维码
     * 最好是部署在单独的服务器上
     */
    @RequestMapping("/shortUrl")
    public void shortUrl(HttpServletRequest request, HttpServletResponse response){
    	logger.info("enter method shortUrl().");
    	
    	try {
    		// 获取参数
    		String longUrl = request.getParameter("longUrl");
    		if(StringUtils.isEmpty(longUrl)) {
    			return;
    		}
    		
    		// 从长链接里获取协议头+端口号+域名
    		String basePath = IpUtil.getProtocolAndDomainAndPort(longUrl);
    		
    		// 生成短链接
    		String shortUrl = ShortUrlUtil.generateShortUrl(longUrl);
    		
    		// 保存短链接和长链接的绑定关系到redis中（也可以是其他存储）
    		String redisKey = MessageFormat.format(RedisConstants.REDIS_KEY_SHORTURL, shortUrl);
            String redisValue = longUrl.substring(basePath.length()); // 截取长链接的后半部分作为value
            if(JedisUtil.exists(redisKey)) { // 如果key已经存在，则重新生成
            	shortUrl = ShortUrlUtil.generateShortUrl(longUrl);
            	redisKey = MessageFormat.format(RedisConstants.REDIS_KEY_SHORTURL, shortUrl);
            	if(JedisUtil.exists(redisKey)) { // 如果key仍然存在，则返回错误
            		return;
            	}
            }
            JedisUtil.setex(redisKey, redisValue, 30*60); // 30分钟有效
    		
    		// 二维码的内容
    		String content = basePath + "/" + shortUrl;
    		
    		// 嵌入二维码的LOGO图片
    		String logoPath = "d:/qrCode/logo.jpg";
    		
    		OutputStream os = response.getOutputStream();
    		QRCodeUtil.encode(content, logoPath, os); // 生成二维码
            os.flush();
            os.close();
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    }

    /**
     * 扫描二维码，解析短链接
     */
//    @RequestMapping("/{shortUrl}")
    public ModelAndView getUrl(HttpServletRequest request, @PathVariable(value = "shortUrl") String shortUrl){
    	logger.info("enter method getUrl(). shortUrl:{}", shortUrl);
		if(StringUtils.isEmpty(shortUrl)) {
			return null;
		}
		
		// 根据短链接key，从redis中获取长链接
		String redisKey = MessageFormat.format(RedisConstants.REDIS_KEY_SHORTURL, shortUrl);
		String redisValue = JedisUtil.get(redisKey);
		if(StringUtils.isEmpty(redisValue)) {
			logger.info("getUrl|二维码已失效");
			return null;
		}
		
		// 拼接完整的长链接
		String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath();
		if(request.getServerPort()==80) {
			basePath = request.getScheme()+"://"+request.getServerName()+request.getContextPath();
		}
		String longUrl = basePath + redisValue;
		logger.info("getUrl|longUrl:{}", longUrl);
    	
    	// redirect到长链接
    	ModelAndView mav = new ModelAndView(new RedirectView(longUrl));
    	return mav;
    }
}
